[−][src]Crate evm
SputnikVM implementation, traits and structs.
SputnikVM works on two different levels. It handles:
- a transaction, or
- an Ethereum execution context.
To interact with the virtual machine, you usually only need to work with VM methods.
A SputnikVM's Lifecycle
A VM can be started after it is given a Transaction
(or
Context
) and a BlockHeader
. The user can then fire
or step
to run it. fire
runs the EVM code
(given in field code
of the transaction) until it finishes or
cannot continue. However step
only runs at most one instruction. If the virtual machine needs
some information (accounts in the current block, or block hashes
of previous blocks) it fails, returning a
RequireError
enumeration. With
the data returned in the RequireError
enumeration, one can use
the methods
commit_account
and
commit_blockhash
to
commit the information to the VM. fire
or step
can be
subsequently called to restart from that point. The current VM
status can always be obtained using the status
function. Again,
see VM for a list of methods that can be applied.
Patch: Specifying a Network and Hard-fork
Every VM is associated with a Patch
. This patch tells the VM
which Ethereum network and which hard fork it is on. You will need
to specify the patch as the type parameter. To interact with
multiple patches at the same time, it is recommended that you use
trait objects.
The example below creates a new SputnikVM and stores the object in
vm
which can be used to fire
, step
or get status on. To do
this, it must first create a transaction and a block header. The
patch associated with the VM is either EmbeddedPatch
or
VMTestPatch
depending on an arbitrary block number value set at
the beginning of the program.
use evm::{EmbeddedPatch, VMTestPatch, HeaderParams, ValidTransaction, TransactionAction, VM, SeqTransactionVM}; use bigint::{Gas, U256, Address}; use std::rc::Rc; fn main() { let block_number = 1000; let transaction = ValidTransaction { caller: Some(Address::default()), gas_price: Gas::zero(), gas_limit: Gas::max_value(), action: TransactionAction::Create, value: U256::zero(), input: Rc::new(Vec::new()), nonce: U256::zero() }; let header = HeaderParams { beneficiary: Address::default(), timestamp: 0, number: U256::zero(), difficulty: U256::zero(), gas_limit: Gas::zero() }; let cfg_before_500 = VMTestPatch::default(); let cfg_after_500 = EmbeddedPatch::default(); let vm = if block_number < 500 { SeqTransactionVM::new( &cfg_before_500, transaction, header ); } else { SeqTransactionVM::new( &cfg_after_500, transaction, header ); }; }
Transaction Execution
To start a VM on the Transaction level, use the TransactionVM
struct. Usually, you want to use the sequential memory module
which can be done using the type definition
SeqTransactionVM
.
Calling TransactionVM::new
or SeqTransactionVM::new
requires
the transaction passed in to be valid (according to the rules for
an Ethereum transaction). If the transaction is invalid, the VM
will probably panic. If you want to handle untrusted transactions,
you should use SeqTransactionVM::new_untrusted
, which will not
panic but instead return an error if the transaction is invalid.
Context Execution
To start a VM on the Context level, use the ContextVM
struct. Usually, you use the sequential memory module with the
type definition SeqContextVM
. Context execution, as with other
EVM implementations, will not handle transaction-level gas
reductions.
Re-exports
pub use crate::errors::CommitError; |
pub use crate::errors::NotSupportedError; |
pub use crate::errors::OnChainError; |
pub use crate::errors::PreExecutionError; |
pub use crate::errors::RequireError; |
Modules
errors | VM errors |
Structs
AccountState | A struct that manages the current account state for one EVM. |
BlockhashState | A struct that manages the current blockhash state for one EVM. |
Context | A VM context. See the Yellow Paper for more information. |
ContextVM | A VM that executes using a context and block information. |
DynamicAccountPatch | AccountPatch that can be configured in client code runtime |
DynamicPatch | Patch that can be configured in client code runtime |
ECRECPrecompiled | ECREC precompiled contract. |
EmbeddedAccountPatch | Mainnet account patch |
EmbeddedPatch | Embedded patch. |
HeaderParams | Block header. |
IDPrecompiled | ID precompiled contract. |
Log | |
Machine | A VM state with PC. |
PC | Represents a program counter in EVM. |
PCMut | Represents a mutable program counter in EVM. |
RIP160Precompiled | RIP160 precompiled contract. |
Runtime | A VM runtime. Only available in eval. |
SHA256Precompiled | SHA256 precompiled contract. |
SeqMemory | A sequencial memory. It uses Rust's |
Stack | Represents an EVM stack. |
State | A VM state without PC. |
Storage | Internal representation of an account storage. It will return a
|
TransactionVM | A VM that executes using a transaction and block information. |
UntrustedTransaction | Represents an Ethereum transaction. |
VMTestPatch | Patch sepcific for the |
ValidTransaction | Represents an Ethereum transaction. |
Valids | Mapping of valid jump destination from code. |
Enums
AccountChange | Represents an account. This is usually returned by the EVM. |
AccountCommitment | A single account commitment. |
Instruction | Instructions for the program counter. This is the same as |
MachineStatus | Represents the current runtime status. |
Opcode | Opcode enum. One-to-one corresponding to an |
TransactionAction | |
VMStatus | VM Status |
Statics
ECREC_PRECOMPILED | Static value of ECREC precompiled contract. |
EMBEDDED_PRECOMPILEDS | Default precompiled collections. |
ID_PRECOMPILED | Static value of ID precompiled contract. |
RIP160_PRECOMPILED | Static value of RIP160 precompiled contract. |
SHA256_PRECOMPILED | Static value of SHA256 precompiled contract. |
Traits
AccountPatch | Account patch for account related variables. Account patch is always static, as it's usually stays constant for any given network. |
Memory | Represent a memory in EVM. Read should always succeed. Write can fall. |
Patch | Represents different block range context. |
Precompiled | Represent a precompiled contract. |
VM | Represents an EVM. This is usually the main interface for clients to interact with. |
Type Definitions
SeqContextVM | A sequential VM. It uses sequential memory representation and hash map storage for accounts. |
SeqTransactionVM | A sequential transaction VM. This is same as |